/**
 * Copyright 2008 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kiff.service.impl;

import com.google.inject.Inject;

import kiff.dao.ForumAclDAO;
import kiff.dao.GlobalAclDAO;
import kiff.dao.RoleDAO;
import kiff.dao.SettingDAO;
import kiff.entity.ForumAcl;
import kiff.entity.ForumAclEntry;
import kiff.entity.ForumPermission;
import kiff.entity.GlobalAcl;
import kiff.entity.GlobalAclEntry;
import kiff.entity.GlobalPermission;
import kiff.entity.Role;
import kiff.entity.Setting;
import kiff.entity.User;
import kiff.enumerator.RoleStatus;
import kiff.exception.DataLayerException;
import kiff.exception.ServiceLayerException;
import kiff.service.InstallService;
import kiff.service.UserService;
import kiff.util.transaction.annotation.Transactional;

/**
 * An implementation of the InstallService interface.
 * @author Adam
 * @version $Id: InstallServiceImpl.java 67 2008-11-24 06:55:33Z a.ruggles $
 * 
 * Created on Oct 21, 2008 at 01:10:23 PM 
 */
public class InstallServiceImpl implements InstallService {

	/**
	 * Forum Access Control List Data Access Object.
	 */
	private ForumAclDAO forumAclDAO;

	/**
	 * Global Access Control List Data Access Object.
	 */
	private GlobalAclDAO globalAclDAO;

	/**
	 * Role Data Access Object.
	 */
	private RoleDAO roleDAO;

	/**
	 * Setting Data Access Object.
	 */
	private SettingDAO settingDAO;

	/**
	 * User Service.
	 */
	private UserService userService;

	/**
	 * {@inheritDoc}
	 * @see kiff.service.InstallService#install(kiff.entity.User)
	 */
	@Transactional
	public void install(final User administrator, final String ... settings) throws ServiceLayerException {
		try {
			// Create the Administrative User.
			userService.insert(administrator, null);
			// Create the Default Roles for the forum (administrator, user, and guest).
			Role adminRole = new Role("Administrators", "Administrator Role", RoleStatus.REQUIRED);
			Role userRole = new Role("Users", "User Role", RoleStatus.REQUIRED);
			Role moderatorRole = new Role("Moderators", "Moderator Role", RoleStatus.REQUIRED);
			Role guestRole = new Role("Guest", "Guest Role", RoleStatus.REQUIRED);
			roleDAO.insert(adminRole);
			roleDAO.insert(moderatorRole);
			roleDAO.insert(userRole);
			roleDAO.insert(guestRole);
			// Create the Global Access Control List.
			GlobalAcl acl = new GlobalAcl(GlobalAcl.DEFAULT_NAME);
			acl.addEntry(new GlobalAclEntry(adminRole,	new GlobalPermission(GlobalPermission.ADMINISTRATOR)));
			acl.addEntry(new GlobalAclEntry(moderatorRole,	new GlobalPermission(GlobalPermission.MODERATOR)));
			globalAclDAO.insert(acl);
			// Create default Forum Access Control List.
			ForumAcl forumAcl = new ForumAcl(ForumAcl.DEFAULT_NAME);
			forumAcl.addEntry(new ForumAclEntry(adminRole, new ForumPermission(ForumPermission.POST_CREATE
					, ForumPermission.POST_DELETE_ALL, ForumPermission.POST_EDIT_ALL
					, ForumPermission.TOPIC_CREATE, ForumPermission.TOPIC_CREATE_ANNOUNCE
					, ForumPermission.TOPIC_CREATE_STICKY, ForumPermission.TOPIC_DELETE_ALL
					, ForumPermission.TOPIC_LOCK_ALL)));
			forumAcl.addEntry(new ForumAclEntry(moderatorRole, new ForumPermission(ForumPermission.POST_CREATE
					, ForumPermission.POST_DELETE_ALL, ForumPermission.POST_EDIT_ALL
					, ForumPermission.TOPIC_CREATE, ForumPermission.TOPIC_CREATE_ANNOUNCE
					, ForumPermission.TOPIC_CREATE_STICKY, ForumPermission.TOPIC_DELETE_ALL
					, ForumPermission.TOPIC_LOCK_ALL)));
			forumAcl.addEntry(new ForumAclEntry(userRole, new ForumPermission(ForumPermission.POST_CREATE
					, ForumPermission.POST_EDIT_OWN, ForumPermission.TOPIC_CREATE)));
			forumAcl.addEntry(new ForumAclEntry(guestRole, new ForumPermission()));
			forumAclDAO.insert(forumAcl);
			// Add the Administrator to the Administrative Role.
			administrator.getRoles().add(adminRole);
			userService.update(administrator, administrator);
			// Setup default settings.
			settingDAO.insert(new Setting(Setting.GLOBAL_ACL_NAME, GlobalAcl.DEFAULT_NAME));
			settingDAO.insert(new Setting(Setting.VERSION, "1.0"));
			// Add any additional settings.
			int length = settings.length;
			for (int i = 0; i < length; i += 2) {
				Setting setting = new Setting(settings[i], settings[i + 1]);
				settingDAO.insert(setting);
			}
		} catch (DataLayerException dataLayerEx) {
			throw new ServiceLayerException("Install Failed", dataLayerEx);
		}
	}

	/**
	 * Sets forumAclDAO.
	 * @param forumAclDAO the forumAclDAO to set.
	 */
	@Inject
	public void setForumAclDAO(final ForumAclDAO forumAclDAO) {
		this.forumAclDAO = forumAclDAO;
	}

	/**
	 * Sets globalAclDAO.
	 * @param globalAclDAO the globalAclDAO to set.
	 */
	@Inject
	public void setGlobalAclDAO(final GlobalAclDAO globalAclDAO) {
		this.globalAclDAO = globalAclDAO;
	}

	/**
	 * Sets roleDAO.
	 * @param roleDAO the roleDAO to set.
	 */
	@Inject
	public void setRoleDAO(final RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}

	/**
	 * Sets settingDAO.
	 * @param settingDAO the settingDAO to set.
	 */
	@Inject
	public void setSettingDAO(final SettingDAO settingDAO) {
		this.settingDAO = settingDAO;
	}

	/**
	 * Sets userService.
	 * @param userService the userService to set.
	 */
	@Inject
	public void setUserService(final UserService userService) {
		this.userService = userService;
	}

}
